//@auther foolbread
//@time 2016-03-09
//@file ApnsHttp2/statics/statics.go
package statics

import (
	"ApnsHttp2/config"
	"fmt"
	"github.com/foolbread/fbcommon/golog"
	"runtime"
	"sort"
	"sync/atomic"
	"time"
)

func InitStatics() {
	golog.Info("initing ApnsHttp2 statics...")

	infos := config.GetConfigInstance().GetCertificateInfos()
	for k, v := range infos {
		i := &staticsInfo{k, v.Name, 0, 0}
		staticsMap[k] = i
		staticsArray = append(staticsArray, i)
	}

	sort.Sort(ByType{staticsArray})

	go outputStaticsInfo()
}

func outputStaticsInfo() {
	ti := time.Tick(30 * time.Second)
	for {
		<-ti
		var str string
		str = str + fmt.Sprintf("goroutine:%d", runtime.NumGoroutine())

		for _, v := range staticsArray {
			str = str + fmt.Sprintf(" [%s:%d exception:%d]", v.title, atomic.LoadUint64(&v.msg_cnt), atomic.LoadInt64(&v.exc_cnt))
			atomic.StoreUint64(&v.msg_cnt, 0)
		}

		golog.Info(str)
	}
}

func CommitMsgStatics(ty int) {
	i, ok := staticsMap[ty]
	if !ok {
		return
	}

	atomic.AddUint64(&i.msg_cnt, 1)
}

func IncreExcepteMsg(ty int) {
	i, ok := staticsMap[ty]
	if !ok {
		return
	}

	atomic.AddInt64(&i.exc_cnt, 1)
}

func DecreExcepteMsg(ty int) {
	i, ok := staticsMap[ty]
	if !ok {
		return
	}

	atomic.AddInt64(&i.exc_cnt, -1)
}

var staticsMap map[int]*staticsInfo = make(map[int]*staticsInfo)
var staticsArray staticsInfos

type staticsInfo struct {
	ty      int
	title   string
	msg_cnt uint64
	exc_cnt int64
}

type staticsInfos []*staticsInfo

func (s staticsInfos) Len() int {
	return len(s)
}

func (s staticsInfos) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

type ByType struct {
	staticsInfos
}

func (s ByType) Less(i, j int) bool {
	return s.staticsInfos[i].ty < s.staticsInfos[j].ty
}
